/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iteracon.generator.visitor;

import iteracon.generator.RangeBase;
import iteracon.generator.Rng;
import iteracon.generator.iterator.FromToStepIter;
import iteracon.generator.iterator.FromToStepListIter;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * range generator from one integer to another integer increasing in a given step
 * @author martin
 */
public class FromToStep extends RangeBase{
  private final int _from,
                    _to,
                    _step;
  /**
   * constructor
   * @param from as int
   * @param to as int
   * @param step as int
   */
  private FromToStep(int from, int to, int step){
    _from=from;
    _to=to;
    _step=step;
  }
  
  /**
   * static factory
   * @param from as int
   * @param to as int
   * @param step as int
   * @return range generator as List
   */
  public static Rng make(int from, int to, int step){
    return new FromToStep(from,to,step);
  }

  @Override
  public int size() {
    return (_to-_from)/_step;
  }

  @Override
  public Integer get(int index) {
    //if (index<size())
      return _from+index*_step;
    //throw new IndexOutOfBoundsException();
  }

  @Override
  public Iterator<Integer> iterator() {
    return new FromToStepIter(_from,_to,_step);
  }

  @Override
  public ListIterator<Integer> listIterator() {
    return new FromToStepListIter(_from, _to, _step,0);
  }

  @Override
  public ListIterator<Integer> listIterator(int index) {
    return new FromToStepListIter(_from, _to, _step,index);
  }

  @Override
  public List<Integer> subList(int fromIndex, int toIndex) {
    if (fromIndex<0 || toIndex >= size())
      throw new IndexOutOfBoundsException();
    return FromToStep.make(fromIndex*_step, toIndex*_step, _step);  
  }
  
  @Override
  public boolean contains(Object o) {
    //optimization
    if (!(o instanceof Integer))
      return false;
    return ((Integer)o) < _to && ((Integer)o) >= _from && ((Integer)o)%_step==0;
  }
  
  @Override
  public int indexOf(Object o) {
    //optimization
    if (!(o instanceof Integer) || ((Integer)o) >= _to || ((Integer)o) < _from || ((Integer)o)%_step != 0)
      return -1;
    return (((Integer)o)-_from)/_step;
  }

  @Override
  public int lastIndexOf(Object o) {
    //optimization
    return indexOf(o);
  }

  @Override
  public int from() {
    return _from;
  }

  @Override
  public int to() {
    return _to;
  }

  @Override
  public int step() {
    return _step;
  }
}
